# -*- coding: utf-8 -*-

from odoo import models, fields, api
from odoo.exceptions import UserError
from odoo.osv import expression
from odoo.tools import float_is_zero, float_compare


class MrpProduction(models.Model):
    _inherit = 'mrp.production'
    repicking_picking_ids = fields.One2many('stock.picking', 're_picking_production_id', string=u'补料单')

class StockPicking(models.Model):
    _inherit = 'stock.picking'

    re_picking_production_id = fields.Many2one(string=u'制造订单', comodel_name='mrp.production')

    group_name = fields.Char(string=u'补货组名称', related='group_id.name', store=True)

    # partner_shipping_address = fields.Char(string=u'收货地址', related='group_id.partner_shipping_address')



class StockMove(models.Model):
    _inherit = 'stock.move'

    re_picking_production_id = fields.Many2one(string=u'制造订单', comodel_name='mrp.production')




class MrpRepickingWizard(models.TransientModel):
    _name = 'mrp.repicking.wizard'

    @api.model
    def default_raw_repicking_ids(self):
        production_id = self._context.get('re_picking_production_id')
        mo = self.env['mrp.production'].browse(production_id)
        products = mo.move_raw_ids.mapped('product_id')
        vals = []
        for p in products:
            line=mo.consume_line_ids.filtered(lambda x: x.product_id == p)
            vals.append([0, 0, {
                'product_id': p.id,
                'product_qty': 0,
                'max_qty':line.unpicking_qty

            }])
        return vals

    production_id = fields.Many2one(string=u'制造订单', comodel_name='mrp.production')
    raw_repicking_ids = fields.One2many(string=u'补领明细', comodel_name='mrp.repicking.line', inverse_name='repicking_id', default=default_raw_repicking_ids)

    def confirm_to_re_picking(self):
        picking_no_done = self.production_id.get_repicking_pickings().filtered(lambda x: x.state not in ['done', 'cancel'])
        if picking_no_done:
            raise UserError(u'有未完成的补料单,无法再次补料')
        line_vaild = self.raw_repicking_ids.filtered(lambda x: x.product_qty > 0)

        stock_move = self.env["stock.move"].with_context({})
        location_data = {}
        for line in line_vaild:
            if float_compare(line.product_qty,line.max_qty,precision_digits=2)==1:
                raise UserError('领料数量不能大于最大数量')
            rule = line._find_suitable_rule()
            if not rule:
                raise UserError(u'%s 找不到对应的路线' % line.product_id.name)
            else:
                if not location_data.get(rule.location_src_id.id):
                    location_data[rule.location_src_id.id] = line
                else:
                    location_data[rule.location_src_id.id] += line
        for location_id in location_data.keys():
            group = self.create_procurement_group()
            picking = self.create_picking(location_id, group)
            lines = location_data[location_id]
            for line in lines:
                vals = line.create_move_vals(picking)
                vals['group_id'] = group.id
                move = stock_move.create(vals)
                move._action_confirm()

            picking.action_confirm()
            picking.action_assign()

    def create_picking(self, location_id, group):
        warehouse_id = self.production_id.picking_type_id.warehouse_id
        if not warehouse_id:
            raise UserError(u'该作业类型未设置对应仓库')
        chose_warehouse = self.env['stock.warehouse']
        picking_type = self.env["stock.picking.type"].search([('return_type', '=', 'repicking')],
                                                             limit=1)
        if not picking_type:
            raise UserError(u'未找到对应的补料调拨类型')

        pick = self.env['stock.picking'].search([('picking_type_id', '=', picking_type.id),
                                                ('group_id', '=', group.id),
                                                ('location_id', '=', chose_warehouse.lot_stock_id.id)], limit=1)

        if not pick:
            vals = {
                'picking_type_id': picking_type.id,
                'group_id': group.id,
                # 'internal_picking_id': self.id,
                # 'partner_id': self.partner_id.id,
                're_picking_production_id': self.production_id.id,
                'date': fields.datetime.now(),
                'origin': u'补料 ' + self.production_id.name,
                'location_dest_id': self.production_id.location_src_id.id,
                'location_id':  location_id
            }
            pick = self.env['stock.picking'].with_context({}).create(vals)
        return pick

    def create_procurement_group(self):
        return self.env['procurement.group'].create({
            'name': self.production_id.name + u'-补料'
        })
class MrpRepickingLine(models.TransientModel):
    _name = 'mrp.repicking.line'

    repicking_id = fields.Many2one(string=u'补领单', comodel_name='mrp.repicking.wizard')
    product_id = fields.Many2one(string=u'产品', comodel_name='product.product')
    product_qty = fields.Float(string=u'数量')
    max_qty=fields.Float(compute='compute_max_qty',string=u'最大可补领数量')

    def compute_max_qty(self):
        for record in self:
            record.max_qty=record.consume_line_id.unpicking_qty
    consume_line_id = fields.Many2one(string=u'消耗明细', comodel_name='mrp.consume.line', compute='_compute_consume_line_id')

    def _compute_consume_line_id(self):
        for line in self:
            consume_line_id = line.repicking_id.production_id.consume_line_ids.filtered(lambda x: x.product_id == line.product_id)
            line.consume_line_id=consume_line_id.id

    def _check_repicking_valid(self):
        for line in self:
            # unpicking_qty = line.consume_line_id.unpicking_qty
            # unprepare_qty = line.consume_line_id.unprepare_qty
            #if unpicking_qty + unprepare_qty > 0: 两种判断方式 看具体需求
            if not float_is_zero(line.consume_line_id.unpicking_qty, precision_rounding=2) :
                raise UserError(u'%s 还有备料单或领料单未操作,不可进行补料.' % line.product_id.name)

    def _find_suitable_rule(self):

        res = self.env['stock.rule']
        # 根据路线查找到 对应库存的rule
        product_routes = self.product_id.route_ids | self.product_id.categ_id.total_route_ids
        if product_routes:

            res = res.search(expression.AND([[('route_id', 'in', product_routes.ids)],
                                        [('location_id', 'in', [self.repicking_id.production_id.location_src_id.id])]]),
                        order='route_sequence, sequence', limit=1)


        return res


    def create_move_vals(self, picking):
        self.ensure_one()
        move_dest_id = self.consume_line_id.move_ids.filtered(lambda x: x.state not in ['done', 'cancel'])
        return {
            'name': self.repicking_id.production_id.name + u' 补料 ' + self.product_id.name,
            'product_id': self.product_id.id,
            'product_uom': self.product_id.uom_id.id,
            'date': picking.date,
            'date_expected': picking.date,
            'location_id': picking.location_id.id,
            'location_dest_id': picking.location_dest_id.id,
            'picking_id': picking.id,
            'move_dest_ids': [(4,move_dest_id.id)],
            'state': 'draft',
            'picking_type_id': picking.picking_type_id.id,
            'origin': picking.name,
            'warehouse_id': picking.picking_type_id.warehouse_id.id,
            'product_uom_qty': self.product_qty,
            're_picking_production_id': picking.re_picking_production_id.id,
        }